/* Advanced Squares.NET
 *  is an open Source .NET Object-Oriented Drawing Engine.
 * 
 *  This work is subject to the Microsoft Shared Source Reference License (MS-RL)

*/

using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.IO;

namespace needle.Services.Tracer
{
    internal static class U
    {

        public static long CurrentLogLineNumber = 0;
        public static string CurrentLogTry = "";
        public static DateTime CurrentTimestamp;


        public static DateTime LastTimestamp;


        public static StreamWriter LogFile = null;
        public static Hashtable LogTry = new Hashtable();


        public class TryObject
        {
            public string Text = "";
            public DateTime Timestamp;

        }


        static U()
        {
            
#if DEBUG      
            try
            {

                Random rnd = new Random(DateTime.Now.Millisecond);
                string fname = "needle_Debug_" + rnd.Next(10000).ToString() + ".Log";

                if (File.Exists(fname)) File.Delete(fname);

                LogFile = File.CreateText(fname);
            }
            catch (Exception exc)
            {
                throw exc;

            }
#endif
        }


        // Return a Timestamp in string. Usefull for logs.
        public static string Timestamp()
        {
            
            U.LastTimestamp = U.CurrentTimestamp;
            U.CurrentTimestamp = DateTime.Now;
            string Timestamp = "[" + U.CurrentTimestamp.Hour.ToString() + ":" + U.CurrentTimestamp.Minute.ToString() + ":" + U.CurrentTimestamp.Second.ToString() + ":" + U.CurrentTimestamp.Millisecond.ToString() + "]";
            return(Timestamp);
        }

        // Return a TimeSpan between 2 DateTime.
        public static TimeSpan TimeDelta(DateTime Start, DateTime Finish)
        {
            TimeSpan delta = TimeSpan.FromTicks(Finish.Ticks - Start.Ticks);
            return (delta);
        }

        // Return a the time elapsed since the last time we called Timestamp().
        public static string Checkpoint()
        {
            if (U.CurrentLogLineNumber < 1) return ("+[0.0.0]");

            TimeSpan delta = TimeDelta(U.LastTimestamp, U.CurrentTimestamp);
            string sdelta = "+[" + delta.Minutes.ToString() + "." + delta.Seconds.ToString() + "." + delta.Milliseconds.ToString() + "]";
            return(sdelta);
        }

        
        public static string CheckpointTry(TryObject Try)
        {
            TimeSpan delta = TimeDelta(Try.Timestamp, DateTime.Now);
            string sdelta = "+" + delta.Minutes.ToString() + "." + delta.Seconds.ToString() + "." + delta.Milliseconds.ToString();
            return (sdelta);

        }

        // Log something with a timestamp. 
        public static void Log(string Text)
        {
#if DEBUG
            string LogLine = "S# " + CurrentLogLineNumber.ToString() + " " + Timestamp() + " " + Checkpoint() + " " + Text;
            Console.WriteLine(LogLine);
            LogFile.WriteLine(LogLine);
            LogFile.Flush();
            CurrentLogLineNumber++;
#endif
        }

        // Log TRY something with a timestamp. 
        public static long LogTRY(string Text)
        {
#if DEBUG           
            TryObject Try = new TryObject();
            Try.Text = Text;
                        
            Log("TRY " + Text);
            Try.Timestamp = CurrentTimestamp;

            LogTry.Add(CurrentLogLineNumber - 1, Try);
            return (CurrentLogLineNumber - 1);
#else 
            return (0);
#endif
        }

        // Log SUCCEED something with a timestamp. 
        public static void LogSUCCESS(long TryID)
        {
#if (DEBUG)
            if (TryID == -1) return;

            try
            {
                TryObject Try = (TryObject)LogTry[TryID];
                Log("SUCCEED (" + TryID.ToString() + " : " + CheckpointTry(Try) + ") " + Try.Text);
                LogTry.Remove(TryID);
            }
            catch (Exception ex)
            {
                throw ex;
            }

#endif            
        }

        // Log FAILED something with a timestamp.
        public static void LogFAILED(long TryID, Exception ex)
        {
#if DEBUG
            if (TryID == -1) return;

            try
            {
                TryObject Try = (TryObject)LogTry[TryID];
                string LogLine = "FAILED " + Try.Text;
                if (ex != null)
                {
                    LogLine += "\r\n EXCEPTION -> " + ex.Message;

                }
                Log(LogLine);
                LogTry.Remove(TryID);
            }
            catch (Exception exc)
            {
                throw exc;
            }
#endif
        }
        
        // Log FAILED something with a timestamp.
        public static void LogFAILED(long TryID)
        {
#if DEBUG           
            LogFAILED(TryID, null);
#endif
        }
    
    }


}
